﻿// -------------------------------------------------------------------------------------------------------------------------------
// <copyright file="Slae{T}.cs" company="Exul">
//     Copyright (c) Exul. All rights reserved.
// </copyright>
// <author>
//     Exul
// </author>
// -------------------------------------------------------------------------------------------------------------------------------

namespace ExulLibrary.Mathematics.LinearAlgebra
{
    #region Usings

    using System;

    using ExulLibrary.Mathematics.LinearAlgebra.Exceptions;

    #endregion

    /// <summary>
    ///     Represents a system of linear algebraic equations.
    /// </summary>
    /// <typeparam name="T">
    ///     The type of elements of the system.
    /// </typeparam>
    public sealed class Slae<T>
    {
        #region Constructors and Destructors

        #region public

        /// <summary>
        ///     Initializes a new instance of the <see cref="Slae{T}"/> class.
        /// </summary>
        /// <param name="matrix">
        ///     The matrix of the system.
        /// </param>
        /// <param name="rightHandPart">
        ///     The right-hand part of the system.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="matrix"/> is <see langword="null"/>.
        ///     <para>
        ///         --or--
        ///     </para>
        ///     <para>
        ///         <paramref name="rightHandPart"/> is <see langword="null"/>.
        ///     </para>
        /// </exception>
        /// <exception cref="NonSquareMatrixException">
        ///     <paramref name="matrix"/> is a non-square matrix.
        /// </exception>
        /// <exception cref="IncompatibleMatrixVectorException">
        ///     <paramref name="matrix"/> and <paramref name="rightHandPart"/> have incompatible dimensions.
        /// </exception>
        public Slae(Matrix<T> matrix, DenseVector<T> rightHandPart)
        {
            #if SAFE

            if (matrix == null)
            {
                throw new ArgumentNullException("matrix");
            }

            if (rightHandPart == null)
            {
                throw new ArgumentNullException("rightHandPart");
            }

            if (!matrix.IsSquare)
            {
                throw new NonSquareMatrixException("matrix", matrix.RowsCount, matrix.ColumnsCount);
            }

            if (matrix.RowsCount != rightHandPart.Length)
            {
                throw new IncompatibleMatrixVectorException(
                    "matrix", matrix.RowsCount, matrix.ColumnsCount, "rightHandPart", rightHandPart.Length, matrix.ColumnsCount);
            }

            #endif

            this.Matrix = matrix;
            this.RightHandPart = rightHandPart;
        }

        #endregion

        #endregion

        #region Properties

        #region public

        /// <summary>
        ///     Gets the matrix of the system.
        /// </summary>
        /// <value>
        ///     The matrix of the system.
        /// </value>
        public Matrix<T> Matrix
        {
            get;
            private set;
        }

        /// <summary>
        ///     Gets the right-hand part of the system.
        /// </summary>
        /// <value>
        ///     The right-hand part of the system.
        /// </value>
        public DenseVector<T> RightHandPart
        {
            get;
            private set;
        }

        /// <summary>
        ///     Gets the size of the system.
        /// </summary>
        /// <value>
        ///     The size of the system.
        /// </value>
        public int Size
        {
            get
            {
                return this.Matrix.RowsCount;
            }
        }

        #endregion

        #endregion
    }
}